<template>
	<view class="map-wrapper" ref="mapWrapper"
		@touchstart="handleTouchStart"
		@touchmove="handleTouchMove"
		@touchend="handleTouchEnd">
		<view class="map-content" :style="{ transform: `scale(${currentScale}) translate(${currentX}px, ${currentY}px)` }">
			<svg :width="displayWidth" :height="displayHeight" xmlns="http://www.w3.org/2000/svg"
				style="background: transparent;">
				<defs>
					<!-- 机器人渐变 -->
					<radialGradient id="robotGradient" cx="50%" cy="30%" r="70%">
						<stop offset="0%" style="stop-color:#00ff88;stop-opacity:1" />
						<stop offset="70%" style="stop-color:#00cc66;stop-opacity:0.8" />
						<stop offset="100%" style="stop-color:#008844;stop-opacity:0.6" />
					</radialGradient>
					<!-- 轨迹渐变 -->
					<linearGradient id="trajectoryGradient" x1="0%" y1="0%" x2="100%" y2="0%">
						<stop offset="0%" style="stop-color:#00d4ff;stop-opacity:0.8" />
						<stop offset="50%" style="stop-color:#0099cc;stop-opacity:1" />
						<stop offset="100%" style="stop-color:#00d4ff;stop-opacity:0.8" />
					</linearGradient>
					<!-- 起点渐变 -->
					<radialGradient id="startGradient" cx="50%" cy="50%" r="60%">
						<stop offset="0%" style="stop-color:#00ff88;stop-opacity:1" />
						<stop offset="80%" style="stop-color:#00cc66;stop-opacity:0.8" />
						<stop offset="100%" style="stop-color:#008844;stop-opacity:0.4" />
					</radialGradient>
					<!-- 终点渐变 -->
					<radialGradient id="endGradient" cx="50%" cy="50%" r="60%">
						<stop offset="0%" style="stop-color:#ff6b35;stop-opacity:1" />
						<stop offset="80%" style="stop-color:#cc5522;stop-opacity:0.8" />
						<stop offset="100%" style="stop-color:#aa3311;stop-opacity:0.4" />
					</radialGradient>
				</defs>
				<g :transform="`scale(1, -1) translate(0, ${-displayHeight})`">
					<template v-if="mapData && mapData.length > 0">
						<g>
							<rect v-for="(chunk, chunkIndex) in mapChunks" :key="'chunk-'+chunkIndex" :x="chunk.x"
								:y="chunk.y" :width="chunk.width" :height="chunk.height" :class="['cell', chunk.class]"
								:style="chunk.style" />
						</g>
					</template>
					<!-- 等待提示 -->
					<text v-else x="400" y="-300" class="waiting-text" transform="scale(1, -1)">⏳ 等待地图数据...</text>
					<!-- 激光扫描线（使用path元素优化） -->
					<g v-if="showLaserPoints && laserPoints.length > 0">
						<path :d="laserLinesPath" class="laser-line" />
						<path :d="laserPointsPath" class="laser-point" />
					</g>
					<g v-for="(trajectory, trajIndex) in trajectories" :key="'traj-'+trajIndex">
						<!-- 轨迹线 -->
						<polyline v-if="trajectory.length > 1" :points="getTrajectoryPoints(trajectory)"
							:class="getSavedTrajectoryLineClass(trajIndex)" />
						<!-- 轨迹点 -->
						<circle v-for="(point, pointIndex) in trajectory" :key="'traj-'+trajIndex+'-point-'+pointIndex"
							:cx="point.x" :cy="point.y"
							:class="getTrajectoryPointClass(pointIndex, trajectory.length)" />
					</g>
					<!-- 当前录制中的轨迹 -->
					<g v-if="trajectoryRecording && currentTrajectory.length > 0">
						<!-- 当前轨迹线 -->
						<polyline v-if="currentTrajectory.length > 1" :points="getTrajectoryPoints(currentTrajectory)"
							class="trajectory-line"
							style="stroke-dasharray: 5,5; animation: dash 1s linear infinite;" />
						<!-- 当前轨迹点 -->
						<circle v-for="(point, pointIndex) in currentTrajectory" :key="'current-point-'+pointIndex"
							:cx="point.x" :cy="point.y"
							:class="getTrajectoryPointClass(pointIndex, currentTrajectory.length)" />
					</g>
					<!-- 机器人位置（独立渲染） -->
					<g v-if="robotPosition.x !== undefined && robotPosition.y !== undefined"
						:transform="getRobotTransform() + ` scale(1, -1)`">
						<circle class="robot" r="6" />
						<line class="robot-direction" x1="0" y1="0"
							:x2="8 * Math.cos(-robotPosition.yaw * Math.PI / 180)"
							:y2="8 * Math.sin(-robotPosition.yaw * Math.PI / 180)" />
					</g>
				</g>
			</svg>
		</view>
	</view>
</template>

<script>
	import {
		io
	} from 'socket.io-client'
	import {
		connectMqtt,
		subscribe,
		unsubscribe,
		publishMessage
	} from '@/services/mqttService';
	import {
		CoordinateTransformer,
		computeRobotStateUpdate
	} from '@/utils/transformer';
	import {
		expandOccupancy
	} from '@/utils/processMapData.js'
	export default {
		data() {
			return {
				socket: null,
				serverUrl: 'ws://127.0.0.1:5002',
				statusText: '未连接',
				mapData: [],
				displayWidth: 800, // 默认显示尺寸
				displayHeight: 600, // 默认显示尺寸
				width: 0,
				height: 0,
				laserPoints: [],
				showLaserPoints: true,
				trajectories: [],
				currentTrajectory: [],
				trajectoryRecording: false,
				robotPosition: {
					x: 0,
					y: 0,
					yaw: 0,
					power: 0,
					velocity: {
						vx: 0,
						vy: 0,
						vz: 0
					}
				},
				lastUpdateTime: 0,
				UPDATE_INTERVAL: 100, // 更新间隔（毫秒）
				updateTimer: null,
				currentScale: 1, // 初始缩放比例设为1
				currentX: 0, // 当前X偏移
				currentY: 0, // 当前Y偏移
				isExecuting: false,
				// 建图相关
				isMapping: false,
				hasMap: false,
				// 等待地图数据初始化后才能执行获取数据
				isInit: false,
				// 触摸缩放相关
				startY: 0,
				endY: 0,
				startDistance: 0,
				lastScale: 1,
			}
		},
		computed: {
			mapChunks() {
				if (!this.mapData || !this.width) return [];
				const chunks = [];
				const CHUNK_SIZE = 10; // 每个块的大小
				for (let y = 0; y < this.height; y += CHUNK_SIZE) {
					for (let x = 0; x < this.width; x += CHUNK_SIZE) {
						const chunkWidth = Math.min(CHUNK_SIZE, this.width - x);
						const chunkHeight = Math.min(CHUNK_SIZE, this.height - y);

						// 检查这个块中的所有单元格
						let allSame = true;
						const firstValue = this.mapData[y * this.width + x];
						const firstClass = this.getCellClass(firstValue);
						const firstStyle = this.getCellStyle(firstValue);

						for (let dy = 0; dy < chunkHeight && allSame; dy++) {
							for (let dx = 0; dx < chunkWidth && allSame; dx++) {
								const index = (y + dy) * this.width + (x + dx);
								if (this.getCellClass(this.mapData[index]) !== firstClass) {
									allSame = false;
								}
							}
						}

						if (allSame) {
							chunks.push({
								x: this.getX(y * this.width + x),
								y: this.getY(y * this.width + x),
								width: chunkWidth,
								height: chunkHeight,
								class: firstClass,
								style: firstStyle
							});
						} else {
							// 如果不是所有单元格都相同，则单独处理每个单元格
							for (let dy = 0; dy < chunkHeight; dy++) {
								for (let dx = 0; dx < chunkWidth; dx++) {
									const index = (y + dy) * this.width + (x + dx);
									chunks.push({
										x: this.getX(index),
										y: this.getY(index),
										width: 1,
										height: 1,
										class: this.getCellClass(this.mapData[index]),
										style: this.getCellStyle(this.mapData[index])
									});
								}
							}
						}
					}
				}
				return chunks;
			},
			// 激光线路径优化
			laserLinesPath() {
				if (!this.showLaserPoints || !this.laserPoints.length) return '';
				return this.laserPoints.map(point =>
					`M${this.robotPosition.x},${this.robotPosition.y} L${point.x},${point.y}`
				).join(' ');
			},

			// 激光点路径优化
			laserPointsPath() {
				if (!this.showLaserPoints || !this.laserPoints.length) return '';
				return this.laserPoints.map(point =>
					`M${point.x},${point.y} m-1,0 a1,1 0 1,0 2,0 a1,1 0 1,0 -2,0`
				).join(' ');
			},
		},
		methods: {
			async initMqtt() {
				// 初始化转换器
				const transformer = new CoordinateTransformer();


				// map
				this._dataHandler = (topic, msg) => {
					try {
						// ---------------雷达数据更新---------------
						if (topic === "scan" && this.isInit) {
							// console.log(JSON.parse(msg.toString()).cmd_type)
							const scanData = JSON.parse(msg.toString())
							const scanLaserPoints = transformer.processLaserScan(scanData)
							this.laserPoints = scanLaserPoints;
						}
						// ---------------车辆状态数更新---------------
						else if (topic === "base_status" && this.isInit) {
							const baseStatusData = JSON.parse(msg.toString());
							// 输出车辆位置
							const {
								robotDisplay,
								world
							} = computeRobotStateUpdate(baseStatusData, transformer);
							this.robotPosition = robotDisplay
						}
						// ---------------地图数据更新---------------
						else if (topic === "map") {
							// console.log(JSON.parse(msg.toString()).cmd_type)
							const mapData = JSON.parse(msg.toString())
							console.log(mapData)
							// 处理地图数据
							const width = mapData["width"]
							const height = mapData["height"]
							const resolution = mapData["resolution"]
							const origin_x = mapData["pose"]["x"]
							const origin_y = mapData["pose"]["y"]
							const origin_yaw = mapData["pose"]["yaw"]
							const map_data = mapData["data"]
							const mode = Number(mapData["mode"] || 0)
							transformer.updateParams(width, height, resolution, origin_x, origin_y);
							const occupancy = expandOccupancy(map_data, width, height, mode)
							const mapDataUpdate = {
								'width': width,
								'height': height,
								'resolution': resolution,
								'origin_x': origin_x,
								'origin_y': origin_y,
								'origin_yaw': origin_yaw,
								'occupancy': occupancy.slice(0, width * height),
								'display_width': transformer.display_width,
								'display_height': transformer.display_height
							}
							this.updateMapData(mapDataUpdate)
						}
					} catch (e) {
						console.error(e)
					}
				}
				// 待完善
				this._feedbackHandler = (topic, msg) => {
					try {
						console.log(JSON.parse(msg.toString()).cmd_type)
					} catch (e) {
						console.error("错误")
					}
				}
				try {
					await connectMqtt();
					subscribe('map', this._dataHandler);
					subscribe('scan', this._dataHandler);
					subscribe('base_status', this._dataHandler);

					subscribe('feedback', this._dataHandler);

					this.subscribed = true;
					// 首次进入页面后立即请求一次地图
					this.requestMap();
				} catch (e) {
					uni.showToast({
						title: 'MQTT 连接失败',
						icon: 'none'
					});
				}













				// if (this.socket) {
				// 	try {
				// 		this.socket.disconnect();
				// 	} catch (e) {}
				// 	this.socket = null;
				// }

				// // 建议明确 transports: ['websocket']
				// this.socket = io(this.serverUrl, {
				// 	transports: ['websocket'], // 强制 websocket（可选）
				// 	autoConnect: true,
				// 	reconnection: true,
				// 	reconnectionAttempts: Infinity,
				// 	reconnectionDelay: 1000,
				// 	reconnectionDelayMax: 5000
				// });

				// this.socket.on('connect', () => {
				// 	this.statusText = '已连接';
				// 	console.log('[socket.io] connected', this.socket.id);
				// });

				// this.socket.on('disconnect', (reason) => {
				// 	this.statusText = '已断开';
				// 	console.log('[socket.io] disconnected', reason);
				// });

				// this.socket.on('connect_error', (err) => {
				// 	this.statusText = '连接错误';
				// 	console.error('[socket.io] connect_error', err);
				// });
				// // 处理初始数据
				// this.socket.on('initial_data', data => {
				// 	console.log('接收初始数据:', data);
				// 	if (data.map && data.map.occupancy) {
				// 		console.log(
				// 			`地图大小: ${data.map.width}x${data.map.height}, 数据长度: ${data.map.occupancy.length}`
				// 		);
				// 	}
				// 	this.updateMapData(data);
				// });
				// // 处理地图更新
				// this.socket.on('map_update', data => {
				// 	console.log('地图更新:', data);
				// 	this.updateMapData(data);
				// });
				// // 处理机器人位置更新
				// this.socket.on('robot_update', robotData => {
				// 	// console.log('机器人位置更新:', robotData);
				// 	this.robotPosition = robotData;
				// });
				// // 处理激光数据更新
				// this.socket.on('laser_update', data => {
				// 	// console.log('激光 数据更新:', data);
				// 	this.laserPoints = data.laser.points;
				// });
				// // 处理轨迹更新
				// this.socket.on('trajectory_update', data => {
				// 	this.trajectoryRecording = data.is_recording;
				// 	this.currentTrajectory = data.current_trajectory || [];
				// });
				// // 处理轨迹录制开始
				// this.socket.on('trajectory_recording_started', data => {
				// 	if (data.success) {
				// 		this.trajectoryRecording = true;
				// 		this.currentTrajectory = [];
				// 		console.log('轨迹记录开始');
				// 	}
				// });
				// // 处理轨迹录制停止
				// this.socket.on('trajectory_recording_stopped', data => {
				// 	console.log('轨迹录制停止:', data);
				// 	if (data.success) {
				// 		this.trajectoryRecording = false;
				// 		// 请求更新轨迹数据
				// 		this.requestUpdatedTrajectories();
				// 		console.log(`Trajectory recording stopped. Total trajectories: ${data.trajectory_count}`);
				// 	}
				// });
				// // 处理轨迹保存结果
				// this.socket.on('trajectory_save_result', data => {
				// 	console.log('接收轨迹保存结果:', data);
				// 	if (data.success) {
				// 		alert(`轨迹保存成功！\n${data.message}`);
				// 		console.log('轨迹保存:', data.data);
				// 	} else {
				// 		alert(`轨迹保存失败：${data.message}`);
				// 		console.error('保存失败:', data);
				// 	}
				// });
				// // 处理轨迹清除
				// this.socket.on('trajectories_cleared', data => {
				// 	if (data.success) {
				// 		this.trajectories = [];
				// 		this.currentTrajectory = [];
				// 		this.trajectoryRecording = false;
				// 		this.selectedTrajectory = 0;
				// 		this.isExecuting = false;
				// 		console.log('所有轨迹清除');
				// 	}
				// });
				// // 处理单条轨迹删除
				// this.socket.on('trajectory_deleted', data => {
				// 	if (data.success) {
				// 		// 重新获取轨迹数据
				// 		this.requestUpdatedTrajectories();
				// 		this.selectedTrajectory = data.new_selected;
				// 		if (data.total_trajectories === 0) {
				// 			this.isExecuting = false;
				// 		}
				// 		console.log(`轨迹 ${data.deleted_index} 删除. 剩下的: ${data.total_trajectories}`);
				// 	} else {
				// 		alert(`删除轨迹失败：${data.message}`);
				// 	}
				// });
				// // 处理轨迹数据更新
				// this.socket.on('trajectories_updated', data => {
				// 	if (data.success) {
				// 		this.trajectories = data.trajectories;
				// 		console.log(`Trajectories updated: ${data.total_count} trajectories`);
				// 	}
				// });
				// // 处理任务执行结果
				// this.socket.on('trajectory_execution_result', data => {
				// 	if (data.success) {
				// 		if (data.message.includes('Started')) {
				// 			this.isExecuting = true;
				// 			console.log('弹道执行开始');
				// 		} else if (data.message.includes('stopped')) {
				// 			this.isExecuting = false;
				// 			console.log('Trajectory execution stopped');
				// 		}
				// 		console.log('Execution command:', data.data);
				// 	} else {
				// 		alert(`任务执行失败：${data.message}`);
				// 	}
				// });

				// // 处理参数更新确认
				// this.socket.on('trajectory_params_updated', data => {
				// 	if (data.success) {
				// 		console.log('Trajectory parameters updated:', data.params);
				// 	}
				// });

				// // 处理调试结果
				// this.socket.on('debug_result', data => {
				// 	console.log('=== DEBUG RESULT FROM SERVER ===');
				// 	console.log('Server trajectory_count:', data.trajectory_count);
				// 	console.log('Server is_recording:', data.is_recording);
				// 	console.log('Server trajectories_details:', data.trajectories_details);

				// 	alert(
				// 		`服务器状态：\n轨迹数量: ${data.trajectory_count}\n录制状态: ${data.is_recording}\n轨迹详情: ${data.trajectories_details.join(', ')} 个点`
				// 	);
				// });

				// // 处理地图请求结果
				// this.socket.on('map_request_result', data => {
				// 	console.log('Map request result:', data);
				// 	if (data.success) {
				// 		console.log('✅ Map request sent successfully');
				// 	} else {
				// 		console.log('❌ Failed to send map request');
				// 		alert('地图请求失败：MQTT连接问题');
				// 	}
				// });

				// // 处理建图状态更新
				// this.socket.on('mapping_status', data => {
				// 	this.isMapping = data.is_mapping;
				// 	this.hasMap = data.has_map;
				// 	if (data.message) {
				// 		alert(data.message);
				// 	}
				// });

				// // 处理地图保存结果
				// this.socket.on('map_save_result', data => {
				// 	if (data.success) {
				// 		alert('地图保存成功！');
				// 	} else {
				// 		alert('地图保存失败：' + data.message);
				// 	}
				// });

				// // 处理所有数据请求结果
				// this.socket.on('all_data_request_result', data => {
				// 	console.log('All data request result:', data);
				// 	if (data.success) {
				// 		console.log('✅ All data requests sent successfully');
				// 	}
				// });
			},
			requestMap() {
				const payload = {
					cmd: 'get',
					cmd_type: 'slam_map_control'
				};
				const ok = publishMessage('robot_control', JSON.stringify(payload));
				if (!ok) {
					uni.showToast({
						title: '发送初始化地图请求失败，稍后自动重试',
						icon: 'none'
					});
				}
				this.isInit = true;
			},
			getCellClass(value) {
				if (value === -1) return 'unknown';
				return value > 50 ? 'occupied' : 'free';
			},
			// 科技黄到黑
			getCellStyle(value) {
				if (value === -1) return {};
				// 0-100 映射到黑色到科技黄
				// 黑色: #000 (hsl(48, 100%, 10%)), 科技黄: #ffe600 (hsl(48, 100%, 50%))
				// 用hsl插值，hue=48, sat=100%，lightness 10%~50%
				const intensity = Math.min(100, Math.max(0, value)) / 100;
				const hue = 48;
				const sat = 100;
				const light = 10 + intensity * 40; // 10%~50%亮度，越大越黄
				return {
					fill: `hsl(${hue}, ${sat}%, ${light}%)`
				};
			},
			getX(index) {
				if (!this.width) return 0;
				const x = index % this.width;
				const offset = (this.displayWidth - this.width) / 2;
				return Math.floor(x + offset);
			},
			getY(index) {
				if (!this.width) return 0;
				const y = Math.floor(index / this.width);
				const offset = (this.displayHeight - this.height) / 2;
				return Math.floor(y + offset);
			},
			getTrajectoryPoints(trajectory) {
				return trajectory.map(point => `${point.x},${point.y}`).join(' ');
			},
			getSavedTrajectoryLineClass(trajIndex) {
				if (trajIndex === this.selectedTrajectory && this.trajectories.length > 1) {
					return 'trajectory-selected';
				}
				return 'trajectory-saved';
			},
			getTrajectoryPointClass(pointIndex, totalPoints) {
				if (pointIndex === 0) return 'trajectory-start';
				if (pointIndex === totalPoints - 1) return 'trajectory-end';
				return 'trajectory-point';
			},
			getRobotTransform() {
				return `translate(${this.robotPosition.x}, ${this.robotPosition.y})`;
			},
			updateMapData(data) {
				const now = Date.now();
				if (now - this.lastUpdateTime < this.UPDATE_INTERVAL) {
					// 如果距离上次更新时间太短，则延迟更新
					clearTimeout(this.updateTimer);
					this.updateTimer = setTimeout(() => {
						this.performMapUpdate(data);
					}, this.UPDATE_INTERVAL);
					return;
				}

				this.performMapUpdate(data);
			},
			performMapUpdate(data) {
				console.log('更新地图数据...');
				if (!data) {
					console.error('Invalid data received:', data);
					return;
				}

				// 批量更新数据，避免多次触发重渲染
				this.$nextTick(() => {
					// 更新地图基本信息
					const mapUpdates = {
						width: data.width,
						height: data.height,
						displayWidth: data.display_width,
						displayHeight: data.display_height,
						resolution: data.resolution,
						mapData: data.occupancy
					};

					// 更新机器人和激光数据
					// const robotUpdates = {
					// 	robotPosition: data.robot,
					// };

					// 更新轨迹数据
					// const trajectoryUpdates = {};
					// if (data.trajectory) {
					// 	Object.assign(trajectoryUpdates, {
					// 		trajectoryRecording: data.trajectory.is_recording,
					// 		currentTrajectory: data.trajectory.current_trajectory || [],
					// 		trajectories: data.trajectory.all_trajectories || [],
					// 		selectedTrajectory: data.trajectory.selected_trajectory || 0,
					// 		isExecuting: data.trajectory.is_executing || false
					// 	});

					// 	if (data.trajectory.execution_params) {
					// 		trajectoryUpdates.executionParams = {
					// 			...this.executionParams,
					// 			...data.trajectory.execution_params
					// 		};
					// 	}
					// }

					// 批量应用更新
					// Object.assign(this, mapUpdates, robotUpdates, trajectoryUpdates);
					Object.assign(this, mapUpdates);

					// 更新位置和缩放
					this.calculateMapPosition();

					// 更新时间戳
					this.lastUpdateTime = Date.now();
				});

				console.log(`更新: ${this.width}x${this.height}, cells: ${this.mapData.length}`);
			},
			calculateMapPosition() {
				if (this.width && this.height) {
					const wrapper = this.$refs.mapWrapper;
					if (wrapper) {
						const containerWidth = wrapper.clientWidth;
						const containerHeight = wrapper.clientHeight;

						// 计算地图在当前缩放比例下的实际尺寸
						const mapWidth = this.width;
						const mapHeight = this.height;

						// 计算居中位置（考虑缩放）
						this.currentX = (containerWidth / this.currentScale - mapWidth) / 2;
						this.currentY = (containerHeight / this.currentScale - mapHeight) / 2;
					}
				}
				// 保存当前缩放倍数
				this.saveMapScale();
			},
			saveMapScale() {
				localStorage.setItem('mapScale', this.currentScale.toString());
			},
			requestUpdatedTrajectories() {
				// 请求服务器发送更新的轨迹数据
				this.socket.emit('get_trajectories');
			},
			// 触摸事件处理方法
			handleTouchStart(event) {
				if (event.touches.length === 1) {
					// 单指触摸，记录起始位置用于滚动缩放
					this.startY = event.touches[0].clientY;
				} else if (event.touches.length === 2) {
					// 双指触摸，记录起始距离用于捏合缩放
					const touch1 = event.touches[0];
					const touch2 = event.touches[1];
					this.startDistance = Math.sqrt(
						Math.pow(touch2.clientX - touch1.clientX, 2) + 
						Math.pow(touch2.clientY - touch1.clientY, 2)
					);
					this.lastScale = this.currentScale;
				}
			},
			handleTouchMove(event) {
				if (event.touches.length === 1) {
					// 单指移动，记录结束位置
					this.endY = event.touches[0].clientY;
				} else if (event.touches.length === 2) {
					// 双指移动，计算距离变化进行缩放
					const touch1 = event.touches[0];
					const touch2 = event.touches[1];
					const currentDistance = Math.sqrt(
						Math.pow(touch2.clientX - touch1.clientX, 2) + 
						Math.pow(touch2.clientY - touch1.clientY, 2)
					);
					
					if (this.startDistance > 0) {
						const scaleChange = currentDistance / this.startDistance;
						const newScale = this.lastScale * scaleChange;
						this.setScale(Math.max(0.5, Math.min(3, newScale)));
					}
				}
				// 阻止默认行为
				event.preventDefault();
			},
			handleTouchEnd() {
				if (this.startY && this.endY) {
					const deltaY = this.endY - this.startY;
					const threshold = 30; // 滚动阈值
					
					if (Math.abs(deltaY) > threshold) {
						if (deltaY > 0) {
							// 向下滚动，缩小
							this.zoomOut();
						} else {
							// 向上滚动，放大
							this.zoomIn();
						}
					}
				}
				
				// 重置触摸状态
				this.startY = 0;
				this.endY = 0;
				this.startDistance = 0;
			},
			// 缩放方法
			zoomIn() {
				const newScale = Math.min(3, this.currentScale + 0.2);
				this.setScale(newScale);
			},
			zoomOut() {
				const newScale = Math.max(0.5, this.currentScale - 0.2);
				this.setScale(newScale);
			},
			setScale(scale) {
				this.currentScale = scale;
				this.calculateMapPosition();
			},
		},
		onLoad() {
			// 从localStorage恢复缩放比例
			const savedScale = localStorage.getItem('mapScale');
			if (savedScale) {
				this.currentScale = parseFloat(savedScale);
			}
			// 初始化WebSocket
			this.initMqtt();
		}
	}
</script>

<style>
	.map-wrapper {
		position: relative;
		display: flex;
		justify-content: center;
		align-items: center;
		background: rgba(5, 10, 25, 0.95);
		border-radius: 12px;
		overflow: hidden;
		width: 100%;
		height: 100%;
	}

	.map-content {
		transform-origin: center center;
		transition: transform 0.12s ease-out;
		display: inline-block;
		position: relative;
	}

	/* SVG地图样式 - 全新配色方案 */
	.cell {
		stroke: none;
		transition: all 0.3s ease;
	}

	/* 占用区域 - 深蓝紫色，表示障碍物 */
	.occupied {
		fill: #1a1b3e;
		filter: drop-shadow(0 0 1px rgba(100, 120, 200, 0.3));
	}

	/* 自由区域 - 深色背景，营造深空感 */
	.free {
		fill: #060815;
	}

	/* 未知区域 - 中等深度，神秘色彩 */
	.unknown {
		fill: #101220;
		opacity: 0.8;
	}

	/* 等待状态动画文字 */
	.waiting-text {
		fill: #00d4ff;
		font-size: 16px;
		text-anchor: middle;
		animation: waitingBlink 1.5s ease-in-out infinite;
	}

	/* 激光扫描样式 - 改进版 */
	.laser-line {
		stroke: rgba(235, 102, 45, 1);
		stroke-width: 0.1;
		stroke-linecap: round;
	}

	.laser-point {
		fill: #ee2b2b;
		r: 1;
	}

	/* 轨迹样式 - 全面改进 */
	.trajectory-line {
		stroke: url(#trajectoryGradient);
		stroke-width: 3;
		fill: none;
		filter: drop-shadow(0 0 6px rgba(0, 212, 255, 0.6));
		stroke-linecap: round;
		stroke-linejoin: round;
	}

	/* 机器人样式 - 增强版 */
	.robot {
		fill: url(#robotGradient);
		stroke: #00ff88;
		stroke-width: 2;
		filter:
			drop-shadow(0 0 12px rgba(0, 255, 136, 0.8)) drop-shadow(0 0 24px rgba(0, 255, 136, 0.4));
		animation: robotPulse 2s ease-in-out infinite;
	}



	.robot-direction {
		stroke: #00ff88;
		stroke-width: 3;
		filter: drop-shadow(0 0 8px rgba(0, 255, 136));
		stroke-linecap: round;
	}
</style>